package com.pignest.hotel.servlet;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.jasperreports.engine.JRAbstractExporter;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.export.JRHtmlExporter;
import net.sf.jasperreports.engine.export.JRHtmlExporterParameter;
import net.sf.jasperreports.engine.export.JRPdfExporter;
import net.sf.jasperreports.engine.export.JRXlsExporter;
import net.sf.jasperreports.engine.util.JRLoader;

import org.apache.commons.lang.StringUtils;

import com.pignest.framework.util.Log;
import com.pignest.hotel.servlet.report.BaseReport;
import com.pignest.hotel.servlet.report.CheckoutDetailReport;
import com.pignest.hotel.servlet.report.CheckoutSummaryReport;
import com.pignest.hotel.servlet.report.MemberChargeReport;
import com.pignest.hotel.system.Hotel;
import com.pignest.hotel.system.L;
import com.pignest.hotel.util.DateUtil;

public class ReportServlet extends HttpServlet {
	private static final long serialVersionUID = 4439683831714873061L;
	private static final String FILTER = "report";
	
	public static final String KEY_STARTTIME = "startTime";
	public static final String KEY_ENDTIME = "endTime";
	private static final String KEY_VIEW = "view";
	private static final String KEY_TITLE = "title";
	private static final String KEY_USER = "user";
	private static final String KEY_NOW = "now";
	
	private static final String REPORT_CHECKOUT_SUMMARY = "checkoutSummary";
	private static final String REPORT_CHECKOUT_DETAIL = "checkoutDetail";
	private static final String REPORT_MEMBER_CHARGE = "memberCharge";
	
	private static final String TARGET_HTML = "HTML";
	private static final String TARGET_PDF = "PDF";
	private static final String TARGET_EXCEL = "EXCEL";
	
	private BaseReport getReport(String reportType) {
		BaseReport report = null;
		if (REPORT_CHECKOUT_SUMMARY.equals(reportType)) {
			report = new CheckoutSummaryReport();
		} else if (REPORT_CHECKOUT_DETAIL.equals(reportType)) {
			report = new CheckoutDetailReport();
		} else if (REPORT_MEMBER_CHARGE.equals(reportType)) {
			report = new MemberChargeReport();
		}
		if (report != null)
			report.setReportType(reportType);
		return report;
	}

	@Override
	public final void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doPost(req, resp);
	}
	
	@Override
	public final void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String reportType = getReportType(req.getRequestURI().substring(req.getContextPath().length()));
		BaseReport report = getReport(reportType);
		try {
			report.initParameters(req);
			String jasperPath = getServletContext().getRealPath(report.getJasperPath());
			File jasperFile = new File(jasperPath);
			JasperReport jasperReport = (JasperReport) JRLoader.loadObject(jasperFile.getPath());
			Map<String, Object> parameters = getParameters(report, req);
			
			JRDataSource dataSource = report.getDataSource(req);
			JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, dataSource);
			export(report, req.getParameter(KEY_VIEW), jasperPrint, resp);
		} catch (JRException e) {
			e.printStackTrace();
//			resp.getWriter().write(report.getTitle() + ":" + e.toString());
		} catch (IllegalArgumentException e) {
			resp.setCharacterEncoding("UTF-8");
			String msg = "无效输入";
			if (e.getMessage() != null)
				msg += ":" + e.getMessage();
			resp.getWriter().write(msg);
		}
	}
	
	private String getReportType(String uri) {
		String[] ss = StringUtils.split(uri, '/');
		if (ss == null || ss.length < 2)
			return null;
		if (!ss[0].equals(FILTER))
			return null;
		return ss[1];
	}
	
	private Map<String, Object> getParameters(BaseReport report, HttpServletRequest req) {
		Map<String, Object> parameters = report.getParameters(req);
		if (parameters == null)
			parameters = new HashMap<String, Object>();
		String format = report.getTimeFormat();
		parameters.put(KEY_TITLE, report.getReportName());
		parameters.put(KEY_STARTTIME, DateUtil.toString(report.getStartTime(), format));
		parameters.put(KEY_ENDTIME, DateUtil.toString(report.getEndTime(), format));
		parameters.put(KEY_USER, Hotel.getCurrentUser().getName());
		parameters.put(KEY_NOW, DateUtil.toString(new Date(), BaseReport.TIME_FORMAT));
		return parameters;
	}
	
	private void export(BaseReport report, String target, JasperPrint jasperPrint, HttpServletResponse resp) throws JRException, IOException {
		JRAbstractExporter exporter = getExporter(target, resp);
		exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, "../../images/blank.gif?a=");
		exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
		exporter.exportReport();
		String title = report.getReportName();
		L.log(L.Action.REPORT, title, "");
		Log.i(title);
	}
	
	private JRAbstractExporter getExporter(String target, HttpServletResponse resp) throws IOException {
		JRAbstractExporter exporter = null;
		if (TARGET_EXCEL.equals(target)) {
			exporter = new JRXlsExporter();
			exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, resp.getOutputStream());
			exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, "hotel.xls");
			resp.setContentType("text/x-msdownload");//application/vnd.ms-excel
			resp.addHeader("Content-Disposition", "attachment; filename=\"checkoutSummary-" + DateUtil.toString(new Date(), "MMdd") + ".xls\"");
		} else if (TARGET_PDF.equals(target)) {
			exporter = new JRPdfExporter();
			exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, resp.getOutputStream());
			exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, "hotel.pdf");
			resp.setContentType("text/x-msdownload");//application/pdf
			resp.addHeader("Content-Disposition", "attachment; filename=\"checkoutSummary-" + DateUtil.toString(new Date(), "MMdd") + ".pdf\"");
		} else if (TARGET_HTML.equals(target) || target == null) {
			exporter = new JRHtmlExporter();
			exporter.setParameter(JRExporterParameter.OUTPUT_WRITER, resp.getWriter());
			exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, "hotel.html");
			resp.setContentType("text/html");
			resp.setCharacterEncoding("GBK");
		}
		return exporter;
	}
}
